<template>
  <el-card style="height: 80px">
    <el-form :inline="true" class="form">
      <el-form-item label="用户名:">
        <el-input v-model="keyword" placeholder="请你输入搜索用户名🔍" style="width: 90vh"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" size="default" :disabled="!keyword" @click="search">搜索</el-button>
        <el-button type="primary" size="default" @click="refresh">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>

  <el-card style="margin: 20px 0">
    <el-button type="primary" @click="addUser">添加用户</el-button>
    <el-button type="danger" :disabled="!SelectUser.length" @click="deleteBatch">批量删除</el-button>
    <!--table展示用户信息-->
    <el-table style="margin: 10px 0;" border :data="userArr" @selection-change="selectChange">
      <el-table-column type="selection" width="100px" align="center"></el-table-column>
      <el-table-column label="#" align="center" width="100px" type="index"></el-table-column>
      <el-table-column label="ID" width="100px" align="center" prop="id"></el-table-column>
      <el-table-column label="用户名" width="160px" align="center" prop="username"></el-table-column>
      <el-table-column label="用户昵称" width="160px" align="center" prop="name"></el-table-column>
      <el-table-column label="用户角色" width="160px" align="center" prop="roleName"
                       show-overflow-tooltip></el-table-column>
      <el-table-column label="创建时间" show-overflow-tooltip width="160px" align="center"
                       prop="createTime"></el-table-column>
      <el-table-column label="更新时间" show-overflow-tooltip width="160px" align="center"
                       prop="updateTime"></el-table-column>
      <el-table-column label="操作">
        <template #="{row}">
          <el-button type="primary" size="small" icon="User" @click="setRole(row)">分配角色</el-button>
          <el-button type="warning" size="small" icon="Edit" @click="updateUser(row)">编辑</el-button>
          <el-popconfirm :title="`你确定要删除${row.username}`" width="260px" @confirm="deleteUser(row.id)">
            <template #reference>
              <el-button type="danger" size="small" icon="Delete">删除</el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <!--分页器组件-->
    <el-pagination @current-change="GetUserInfos" @size-change="GetUserInfos(1)"
                   v-model:current-page="pageNo" v-model:page-size="pageSize" :background="true"
                   :page-sizes="[5,7,9,11]" layout="prev,pager,next,jumper,->,sizes,total" :total="total"/>
  </el-card>

  <!--抽屉结构：添加/修改账号信息-->
  <el-drawer v-model="drawer">
    <!--头部-->
    <template #header>
      <h4>{{ userParams.id ? "更新用户" : "添加用户" }}</h4>
    </template>
    <!--身体-->
    <template #default>
      <el-form :model="userParams" :rules="rules" ref="FormVc">
        <el-form-item label="用户姓名" prop="username">
          <el-input placeholder="请填写用户名称" v-model="userParams.username"></el-input>
        </el-form-item>
        <el-form-item label="用户昵称" prop="name">
          <el-input placeholder="请填写用户昵称" v-model="userParams.name"></el-input>
        </el-form-item>
        <el-form-item label="用户密码" prop="password" v-if="!userParams.id">
          <el-input placeholder="请填写用户密码" v-model="userParams.password"></el-input>
        </el-form-item>
      </el-form>
    </template>
    <!--脚步-->
    <template #footer>
      <el-button type="danger" @click="cancel">取消</el-button>
      <el-button type="primary" @click="save">确定</el-button>
    </template>
  </el-drawer>

  <!--抽屉组件：用于分配角色-->
  <el-drawer v-model="drawer1">
    <template #header>
      <h4>分配角色(职位)</h4>
    </template>
    <template #default>
      <el-form>
        <el-form-item label="用户姓名">
          <el-input v-model="userParams.username" :disabled="true"></el-input>
        </el-form-item>
        <el-form-item label="职位列表">
          <el-checkbox @change="handleCheckAllChange" v-model="checkAll" :indeterminate="isIndeterminate">全选
          </el-checkbox>
          <!--显示职位的复选框-->
          <el-checkbox-group v-model="userRoleArr" @change="handleCheckedRoleChange">
            <el-checkbox v-for="(role,index) in allRoleArr" :key="index" :label="role">{{ role.roleName }}</el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </el-form>
    </template>
    <template #footer>
      <el-button type="danger" @click="drawer1=false">取消</el-button>
      <el-button type="primary" @click="confirm">确定</el-button>
    </template>
  </el-drawer>


</template>

<script setup lang="ts">
import {ref, onMounted, reactive} from "vue";
//@ts-ignore
import {
  reqAddOrUpdateUser,
  reqAllRole,
  reqBatRemoveUser,
  reqGetUserInfo,
  reqRemoveUser,
  reqSetUserRole
  //@ts-ignore
} from "@/api/acl/user/userApi.ts";
import {ElMessage, ElNotification} from "element-plus";
//@ts-ignore
import {T_AllRoleResponseData, T_RoleData, T_SetRoleData, T_User, T_UserResponseData} from "@/api/acl/user/type.ts";


//分页器
let pageNo = ref<number>(1);//页码
let pageSize = ref<number>(5);//页容量
let total = ref<number>(0);//用户总个数
//存储全部用户数据
let userArr = ref<T_User[]>([]);
//抽屉
let drawer = ref<boolean>(false);//抽屉的显示/隐藏
//收集用户信息的响应式数据
let userParams = reactive<T_User>({
  username: "",
  name: "",
  password: ""
});
//获取form组件的实例VC
let FormVc = ref<any>();
//抽屉1
let drawer1 = ref<boolean>(false);//控制角色分配的抽屉的显示/隐藏
//存储所有职位的数据
let allRoleArr = ref<T_RoleData[]>([]);
//当前用户已有的职位数据
let userRoleArr = ref<T_RoleData[]>([]);
//顶部复选框全选按钮
let checkAll = ref<boolean>(false);
//设置不确定样式
let isIndeterminate = ref<boolean>(true);
//要批量删除的id数组
let SelectUser = ref<T_User[]>([]);
//收集用户输入的关键字
let keyword = ref<string>('');


//挂载完毕发送请求
onMounted(() => {
  GetUserInfos();
})

//获取用户数据
const GetUserInfos = async (page: number = 1) => {
  pageNo.value = page;
  let result: T_UserResponseData = await reqGetUserInfo(pageNo.value, pageSize.value, keyword.value)
  if (result.code == 200) {
    total.value = result.data.total;
    userArr.value = result.data.records;
  } else {
    ElNotification({type: "error", message: "获取用户信息失败"})
  }
}

//添加用户按钮回调
const addUser = () => {
  drawer.value = true;//显示抽屉
  Object.assign(userParams, {
    id: null,
    username: '',
    name: '',
    password: ''
  });//清空数据
  //清空form组件校验的提示信息
  FormVc.value.resetFields();
}

//更新已有的用户按钮的回调
const updateUser = (user: T_User) => {
  //收集信息
  Object.assign(userParams, user);
  drawer.value = true;//显示抽屉
};

//点击抽屉确定按钮的回调
const save = async () => {
  //保证表单校验全部通过再发送请求
  await FormVc.value.validate();
  //添加新的用户|更新已有用户的账号信息
  let result = await reqAddOrUpdateUser(userParams)
  if (result.code == 200) {
    drawer.value = false;//关闭抽屉
    ElMessage({type: 'success', message: userParams.id ? "更新成功" : "添加成功"});
    //GetUserInfos(userParams.id ? pageNo.value : 1);
    //浏览器自动刷新一次
    window.location.reload();
  } else {
    drawer.value = false;//关闭抽屉
    ElMessage({type: 'error', message: userParams.id ? "更新失败" : "添加失败"});
  }
}

//取消按钮的回调
const cancel = () => {
  drawer.value = false;
}

//自定义校验规则
//@ts-ignore
const validatorUsername = (rule: any, value: any, callBack: any) => {
  //用户名称|昵称，长度至少5位
  if (value.trim().length >= 5) {
    callBack();
  } else {
    callBack(new Error("用户名长度至少5位"))
  }
}
//@ts-ignore
const validatorName = (rule: any, value: any, callBack: any) => {
  //用户名称|昵称，长度至少5位
  if (value.trim().length >= 5) {
    callBack();
  } else {
    callBack(new Error("昵称长度至少5位"))
  }
}
//@ts-ignore
const validatorPassword = (rule: any, value: any, callBack: any) => {
  //用户名称|昵称，长度至少5位
  if (value.trim().length >= 6) {
    callBack();
  } else {
    callBack(new Error("密码长度至少6位"))
  }
}

//表单校验的规则对象
const rules = {
  //用户名字
  username: [{required: true, trigger: 'change', validator: validatorUsername}],
  //名称
  name: [{required: true, trigger: 'change', validator: validatorName}],
  //密码
  password: [{required: true, trigger: 'change', validator: validatorPassword}]
}

//分配角色的回调
const setRole = async (user: T_User) => {
  //存储已有的用户信息
  Object.assign(userParams, user);
  //发送请求，获取职位信息
  let result: T_AllRoleResponseData = await reqAllRole(userParams.id);
  if (result.code == 200) {
    allRoleArr.value = result.data.allRolesList;//全部的职位
    userRoleArr.value = result.data.assignRoles;//当前用户的职位
    //打开抽屉
    drawer1.value = true;
  } else {
    ElMessage({type: "error", message: "获取角色失败！"})
  }
}

//顶部全部复选框的change事件
const handleCheckAllChange = (val: boolean) => {
  userRoleArr.value = val ? allRoleArr.value : [];
  isIndeterminate.value = false;//不确定的样式
}

//复选框的change回调
const handleCheckedRoleChange = (value: string[]) => {
  checkAll.value = value.length === allRoleArr.value.length;//勾选项目的个数与全部的项目长度相等，则全选应该打勾
  //不确定的样式
  isIndeterminate.value = value.length !== allRoleArr.value.length;
}

//确定按钮的回调（分配职位）
const confirm = async () => {
  //收集参数
  let data: T_SetRoleData = {
    userId: userParams.id,
    roleIdList: userRoleArr.value.map(item => item.id)
  }
  //发送请求
  let result: any = await reqSetUserRole(data)
  if (result.code == 200) {
    //关闭抽屉
    ElMessage({type: "success", message: "分配成功"})
  } else {
    ElMessage({type: "error", message: "分配失败"})
  }
  //重新获取数据
  GetUserInfos(pageNo.value);
  drawer1.value = false;
}

//根据用户id删除用户
const deleteUser = async (userId: number) => {
  let result: any = await reqRemoveUser(userId)
  if (result.code == 200) {
    ElMessage({type: "success", message: "删除成功"})
    GetUserInfos(userArr.value.length > 1 ? pageNo.value : pageNo.value - 1);//重新获取数据
  } else {
    ElMessage({type: "error", message: "删除失败"})
  }
}

//复选框勾选时会触发的事件
const selectChange = (value: any) => {
  SelectUser.value = value;
}

//批量删除的回调
const deleteBatch = async () => {
  //整理批量删除的参数
  let idList: number[] = SelectUser.value.map(item => {
    return item.id
  })
  //批量删除的请求
  let result: any = await reqBatRemoveUser(idList);
  if (result.code == 200) {
    ElMessage({type: "success", message: "批量删除成功"})
    GetUserInfos(userArr.value.length > 1 ? pageNo.value : pageNo.value - 1);//重新获取数据
  } else {
    ElMessage({type: "error", message: "批量删除失败"})
  }
}

//搜索按钮的回调
const search = () => {
  //根据关键字，获取用户数据
  GetUserInfos();
  //清空关键字
  keyword.value = '';
}

//重置按钮的回调
const refresh = () => {
  window.location.reload();
}
</script>

<style scoped>
.form {
  display: flex;
  justify-content: space-between;
  align-items: center;
}
</style>